package com.nowcoder.community.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nowcoder.community.entity.Message;
import com.nowcoder.community.entity.PageEntity;
import com.nowcoder.community.mapper.MessageMapper;
import com.nowcoder.community.service.IMessageService;
import com.nowcoder.community.util.SensitiveFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.util.HtmlUtils;

import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author ChenJH
 * @since 2022-12-26
 */
@Service
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements IMessageService {

    @Autowired
    SensitiveFilter sensitiveFilter;

    //    查询当前用户的会话列表 针对每个会话只返回一条最新消息

    @Override
    public Page<Message> selectConversations(int userId, PageEntity pageEntity) {
        LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
        wrapper.inSql(Message::getId, "select max(id) from message " +
                "where status != 2 " +
                "and from_id != 1 " +
                "and (from_id = " + userId + " or to_id = " + userId + ")" +
                "group by conversation_id");
        wrapper.orderByDesc(Message::getCreateTime);
        Page<Message> page = page(pageEntity.toPage(), wrapper);
        return page;
    }

    //    查询当前用户的会话数量

    @Override
    public int selectConversationCount(int userId) {
        LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
        wrapper.inSql(Message::getId, "select max(id) from message " +
                "where status != 2 " +
                "and from_id != 1 " +
                "and (from_id = " + userId + " or to_id = " + userId + ")" +
                "group by conversation_id");
        return (int) count(wrapper);
    }
//    查询某个会话 包含的私信列表

    @Override
    public Page<Message> selectLetters(String conversationId, PageEntity pageEntity) {
        LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
        wrapper.ne(Message::getStatus, 2);
        wrapper.ne(Message::getFromId, 1);
        wrapper.eq(Message::getConversationId, conversationId).orderByDesc(Message::getId);
        return page(pageEntity.toPage(), wrapper);

    }
//    某个会话包含私信数量

    @Override
    public int selectLetterCount(String conversationId) {
        LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
        wrapper.ne(Message::getStatus, 2);
        wrapper.ne(Message::getFromId, 1).eq(Message::getConversationId, conversationId);
        return (int) count(wrapper);

    }
//    查询未读私信数量

    @Override
    public int selectLetterUnreadCount(int userId, String conversationId) {
        LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Message::getStatus, 0);
        wrapper.ne(Message::getFromId, 1);
        wrapper.eq(Message::getToId, userId);
        if (conversationId != null) {
            wrapper.eq(Message::getConversationId, conversationId);
        }
        return (int) count(wrapper);
    }

    @Override
    public boolean updateStatus(List<Integer> ids, int status) {
        boolean flag = true;
        for (Integer id : ids) {
            LambdaUpdateWrapper<Message> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(Message::getId, id).set(Message::getStatus, status);
            flag = update(wrapper);
        }

        return flag;
    }

    @Override
    public boolean readMessage(List<Integer> ids) {

        boolean flag = true;
        for (Integer id : ids) {
            LambdaUpdateWrapper<Message> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(Message::getId, id).set(Message::getStatus, 1);
            flag = update(wrapper);
        }

        return flag;
    }


    /**
     * 需要过滤敏感词
     *
     * @param message
     * @return
     */
    @Override
    public boolean addMessage(Message message) {
        message.setContent(HtmlUtils.htmlEscape(message.getContent()));
        message.setContent(sensitiveFilter.filter(message.getContent()));

        return save(message);

    }

    @Override
    public Message findLatestNotice(int userId, String topic) {
        LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
        wrapper.inSql(Message::getId, "select max(id) from message" +
                " where status != 2" +
                " and from_id =1" +
                " and to_id = " + userId + "" +
                " and conversation_id = '" + topic + "'");
        Message message = this.getBaseMapper().selectOne(wrapper);
        return message;
    }

    @Override
    public int findNoticeCount(int userId, String topic) {
        LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
        wrapper.ne(Message::getStatus, 2).eq(Message::getFromId, 1).eq(Message::getToId, userId)
                .eq(Message::getConversationId, topic);
        int count = this.getBaseMapper().selectCount(wrapper).intValue();

        return count;
    }

    @Override
    public int findNoticeUnreadCount(int userId, String topic) {
        LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Message::getStatus, 0).eq(Message::getFromId, 1).eq(Message::getToId, userId);
        if (topic != null) {
            wrapper.eq(Message::getConversationId, topic);
        }
        return this.getBaseMapper().selectCount(wrapper).intValue();
    }

    @Override
    public Page<Message> findNotices(int userId, String topic, PageEntity pageEntity) {
        LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
        wrapper.ne(Message::getStatus, 2).eq(Message::getFromId, 1).eq(Message::getToId, userId)
                .eq(Message::getConversationId, topic).orderByDesc(Message::getCreateTime);

        return this.getBaseMapper().selectPage(pageEntity.toPage(), wrapper);
    }


}
